home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / c / gaplib_beta / wizards / conjurer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-14  |  33.9 KB  |  1,658 lines

  1. /*
  2.  * The GAP Conjurer (C)1999 Peter Bengtsson
  3.  *
  4.  * History:
  5.  *
  6.  *        22/4-1999: v1.0
  7.  *
  8.  *
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <ctype.h>
  14. #include <string.h>
  15. #include <time.h>
  16. #include <sys/stat.h>
  17. #include <errno.h>
  18.  
  19. #include "data/bs_c.c"
  20. #include "data/bm_c.c"
  21. #include "data/bv_c.c"
  22. #include "data/sk_c.c"
  23. #include "data/report_h.c"
  24. #include "data/report_c.c"
  25. #include "data/mk.c"
  26.  
  27. const char *__v__="$VER: GAP-Conjurer 1.0 (22.4.99) ©1999 Peter Bengtsson";
  28.  
  29. /* #define    CLEAR    "\x1b" "c"  */
  30.  
  31. #define    CLEAR    "\x1b[H\x1b[J"
  32.  
  33. #define    TF(x)    ((x)?"TRUE":"FALSE")
  34.  
  35. #define    DIR_SEPARATOR    '/'
  36.  
  37. #ifdef    AMIGA
  38. #define    CURRENT_DIR    ""
  39. #else
  40. #define    CURRENT_DIR    "."
  41. #endif
  42.  
  43. #define    Rnd(a)    (rand()%a)
  44. #define    InitRand(a)    srand((unsigned int)a)
  45.  
  46. #define    YES    'Y'
  47. #define    NO        'N'
  48.  
  49. #define    DEFY    "[Y/n]"
  50. #define    DEFN    "[y/N]"
  51.  
  52. #define    MN_IGN    0
  53. #define    MN_STR    1
  54. #define    MN_INT    2
  55. #define    MN_BOL    3
  56.  
  57. #define    WIZFLG_PLOT        (1<<0)
  58. #define    WIZFLG_PSPLOT    (1<<1)
  59. #define    WIZFLG_MPASS    (1<<2)
  60.  
  61. #define    DEF_GENERATIONS    10
  62.  
  63. #define    DEF_BRVLEN    3
  64.  
  65. #define    DEF_NAME    "Manhattan"
  66.  
  67. #define    NUM_DEFNAMES    11
  68.  
  69. char    *includes[] = {
  70.     "stdio",
  71.     "stdlib",
  72.     "string",
  73.     "math",
  74.     "time",
  75.     "GAP",
  76.     NULL
  77. };
  78.  
  79. char    *SelectNames[] = {
  80.     "Double Random",
  81.     "Fitness Proportionate",
  82.     "Sigma Scaled",
  83.     "Tournament",
  84.     "Inorder",
  85.     "Boltzmann",
  86.     "Universal",
  87.     NULL
  88. };
  89.  
  90. char    *RepDefs[] = {
  91.     "AVERAGE",
  92.     "MEDIAN",
  93.     "TYPECOUNT",
  94.     "MAX",
  95.     "MIN",
  96.     "STDDEV"
  97. };
  98.  
  99. char *RepNames[] = {
  100.     "Average",
  101.     "Median",
  102.     "Typecount",
  103.     "Maximum",
  104.     "Minimum",
  105.     "Standard Deviation"
  106. };
  107.  
  108. char *RepExts[] = {
  109.     "avg",
  110.     "med",
  111.     "typ",
  112.     "max",
  113.     "min",
  114.     "dev"
  115. };
  116.  
  117. char    *SelectDefs[] = {
  118.     "DRANDOM",
  119.     "FITPROP",
  120.     "SIGMA",
  121.     "TOURNAMENT",
  122.     "INORDER",
  123.     "TEMPERATURE",
  124.     "UNIVERSAL"
  125. };
  126.  
  127. char    *CrossoverNames[] = {
  128.     "Singlepoint",
  129.     "Multipoint",
  130.     "Custom",
  131.     NULL
  132. };
  133.  
  134. char    *InitNames[] = {
  135.     "Random init",
  136.     "Zero init",
  137.     "Custom init",
  138.     NULL
  139. };
  140.  
  141. char    *CLNames[] = {
  142.     "None",
  143.     "Normal",
  144.     "Verbose",
  145.     "Irritating",
  146.     "Overwhelming",
  147.     NULL
  148. };
  149.  
  150. char    **CLMenu = CLNames;
  151.  
  152. #define    PTYPE_Bitstring    0
  153. #define    PTYPE_Bitmatrix    1
  154. #define    PTYPE_BRVector        2
  155. #define    PTYPE_Custom        3
  156.  
  157. char    *GenomeNames[] = {
  158.     "Bitstring",
  159.     "Bitmatrix",
  160.     "Bounded double vector",
  161.     "Custom",
  162.     NULL
  163. };
  164.  
  165. char    **GenomeMenu = GenomeNames;
  166.  
  167. char    *DefNames[] = {
  168.     "Tourist",
  169.     "Hacker",
  170.     "Gnome",
  171.     "Borg",
  172.     "Bug",
  173.     "Zool",
  174.     "Ghost",
  175.     "Hobbit",
  176.     "Haddock",
  177.     "Dinosaur",
  178.     "Polyphant",
  179.     NULL
  180. };
  181.  
  182. struct VDisp {
  183.     int    Type;
  184.     long    Val;
  185. };
  186.  
  187. char    *Menu1[] = {
  188.     "Project parameters",
  189.     "Population parameters",
  190.     "Make project",
  191.     "Save configuration",
  192.     "Load configuration",
  193.     "Quit",
  194.     NULL
  195. };
  196.  
  197. char    *PrParms[] = {
  198.     "Project name",
  199.     "No. of populations",
  200.     "Comment level",
  201.     "Multiple sourcefiles",
  202.     "GNUPlot script",
  203.     "PostScript plots",
  204.     "Exit",
  205.     NULL
  206. };
  207.  
  208. struct VDisp PrVals[] = {
  209.     {MN_STR,0},
  210.     {MN_INT,0},
  211.     {MN_STR,0},
  212.     {MN_BOL,0},
  213.     {MN_BOL,0},
  214.     {MN_BOL,0},
  215.     {MN_IGN,0}
  216. };
  217.  
  218. char    *PoParms[] = {
  219.     "Change name",
  220.     "Change size",
  221.     "Genome type",
  222.     "Environment parameters",
  223.     "Report parameters",
  224.     "Exit",
  225.     NULL
  226. };
  227.  
  228. struct VDisp PoVals[] = {
  229.     {MN_STR,0},
  230.     {MN_INT,0},
  231.     {MN_STR,0},
  232.     {MN_IGN,0},
  233.     {MN_IGN,0},
  234.     {MN_IGN,0}
  235. };
  236.  
  237. char    *Flags[] = {
  238.     "Init type",
  239.     "Selection method",
  240.     "Crossover",
  241.     "Crowding",
  242.     "Mutation",
  243.     "Pre-mutate",
  244.     "Elitism",
  245.     "Dump worst",
  246.     "Init dumped",
  247.     "Newbies",
  248.     "Erase best",
  249.     "Make stats",
  250.     "Exit",
  251.     NULL
  252. };
  253.  
  254. char    *FlagTags[] = {
  255.     "EVL_Evaluator",
  256.     "EVL_Select",
  257.     "EVL_Crosser",
  258.     "EVL_Crowding",
  259.     "EVL_Mutator",
  260.     "EVL_PreMutate",
  261.     "EVL_Elite",
  262.     "EVL_Dump",
  263.     "EVL_InitDumped",
  264.     "EVL_Newbies",
  265.     "EVL_EraseBest",
  266.     "EVL_Stats"
  267. };
  268.  
  269. struct VDisp FlagVals[] = {
  270.     {MN_STR,0},
  271.     {MN_STR,0},
  272.     {MN_STR,0},
  273.     {MN_BOL,0},
  274.     {MN_BOL,0},
  275.     {MN_BOL,0},
  276.     {MN_INT,0},
  277.     {MN_INT,0},
  278.     {MN_BOL,0},
  279.     {MN_INT,0},
  280.     {MN_BOL,0},
  281.     {MN_BOL,0},
  282.     {MN_IGN,0}
  283. };
  284.  
  285. char    *RFlagMenu[] = {
  286.     "Average",
  287.     "Median",
  288.     "Typecount",
  289.     "Max",
  290.     "Min",
  291.     "Standard Deviation",
  292.     "Toggle All",
  293.     "Runs to average",
  294.     "Exit",
  295.     NULL
  296. };
  297.  
  298. struct VDisp RFlagVals[] = {
  299.     {MN_BOL,0},
  300.     {MN_BOL,0},
  301.     {MN_BOL,0},
  302.     {MN_BOL,0},
  303.     {MN_BOL,0},
  304.     {MN_BOL,0},
  305.     {MN_IGN,0},
  306.     {MN_INT,0},
  307.     {MN_IGN,0}
  308. };
  309.  
  310. struct NPop {
  311.     char    *Name;
  312.     int    Size;
  313.     int    Type;
  314.     int    Flags[12];
  315.     int    RFlags[6];
  316. };
  317.  
  318. struct {
  319.     char    *Name;
  320.     int    NumPops,CLevel;
  321.     struct NPop *Pops;
  322.     int rep,sep,flags,pass;
  323. } Project;
  324.  
  325. char    *MOTD;
  326.  
  327. int    mcount(char **);
  328.  
  329. int    menu(char *,char **,struct VDisp *);
  330. int    msg(char *);
  331. int    int_query(char *,int);
  332. char *str_query(char *,char *);
  333. int    bool_query(char *,int);
  334. void    save_template(char *);
  335. void    load_template(char *);
  336. void    save_pop(FILE *,struct NPop);
  337. void    load_pop(FILE *,int);
  338. void    create_project(char *);
  339. char *addpart(char *,char *);
  340. void filtdump(FILE *,char *,int);
  341. int    file_write(char *);
  342.  
  343.  
  344. int main(int cnt,char *arg[])
  345. {
  346. char    z,buf[255],*tmenu[16],*p;
  347. int    i,n;
  348.  
  349. InitRand(time(NULL));
  350.  
  351. Project.Name=malloc(strlen(DEF_NAME)+1);
  352. strcpy(Project.Name,DEF_NAME);
  353. Project.NumPops=1;
  354. Project.Pops = NULL;
  355. Project.CLevel = 1;
  356. PrVals[0].Val = (long)Project.Name;
  357. PrVals[1].Val = 1;
  358. PrVals[2].Val = (long)CLNames[1];
  359. PrVals[3].Val = 0;
  360. Project.sep=0;
  361. Project.Pops = malloc(sizeof(struct NPop));
  362. memset(Project.Pops,0,sizeof(struct NPop));
  363. Project.Pops[0].Name = malloc(10);
  364. strcpy(Project.Pops[0].Name,"Polyphant");
  365. Project.Pops[0].Flags[4] = 1;    /* Do mutate */
  366. Project.Pops[0].Size = 20;
  367. Project.flags=0;
  368. Project.pass=1;
  369.  
  370. MOTD = malloc(1024);
  371.  
  372. strcpy(MOTD,"Welcome.");
  373.  
  374. switch(cnt) {
  375. case    1:
  376.     z=msg(CLEAR "\nWelcome! This is the GAP Conjurer.\n\nConjure a skeleton? " DEFY " : ");
  377. break;
  378.  
  379. case    2:
  380.     if(strcmp(arg[1],"-h") || strcmp(arg[1],"--help")) {
  381.         fprintf(stderr,"%s [Template] [Dest. Dir]\n",arg[0]);
  382.         goto tixE;
  383.     }
  384.     load_template(arg[1]);
  385.     z = 1;
  386. break;
  387.  
  388. case    3:
  389.     load_template(arg[1]);
  390.     create_project(arg[2]);
  391.     goto tixE;
  392. break;
  393.  
  394. default:
  395.     fprintf(stderr,"%s [Template] [Dest. Dir]\n",arg[0]);
  396.     goto tixE;
  397. }
  398.  
  399. if(toupper(z)!=NO) {
  400.     do {
  401.         i=menu("Main Menu",Menu1,NULL);
  402.         switch(i) {
  403.         case    1:
  404.             do {
  405.                 i = menu("Project parameters",PrParms,PrVals);
  406.                 switch(i) {
  407.                 case    1:    /* Project Name */
  408.                     free(Project.Name);
  409.                     Project.Name = str_query("Project name [" DEF_NAME "] ?",DEF_NAME);
  410.                     PrVals[0].Val = (long)Project.Name;
  411.                     sprintf(MOTD,"Project name is now %s.",Project.Name);
  412.                 break;
  413.  
  414.                 case    2:    /* # of pops */
  415.                     i = int_query("How many populations in project [1] ?",1);
  416.                     if(i>0) {
  417.                         for(n=0;n!=Project.NumPops;n++) {
  418.                             if(Project.Pops[n].Name!=NULL) {
  419.                                 free(Project.Pops[n].Name);
  420.                             }
  421.                         }
  422.                         Project.NumPops = i;
  423.                         PrVals[1].Val = Project.NumPops;
  424.                         if(Project.Pops!=NULL) free(Project.Pops);
  425.                         Project.Pops = malloc(Project.NumPops*sizeof(struct NPop));
  426.                         memset(Project.Pops,0,Project.NumPops*sizeof(struct NPop));
  427.                         n=Rnd(NUM_DEFNAMES);
  428.                         for(i=0;i!=Project.NumPops;i++) {
  429.                             sprintf(buf,"Name for population #%d [%s]? :",i,DefNames[(i+n)%NUM_DEFNAMES]);
  430.                             Project.Pops[i].Name = str_query(buf,DefNames[(i+n)%NUM_DEFNAMES]);
  431.                             Project.Pops[i].Flags[4] = 1;    /* Do mutate */
  432.                             Project.Pops[i].Size = 20;
  433.                         }
  434.                     }
  435.                     sprintf(MOTD,"%d populations created.",Project.NumPops);
  436.                 break;
  437.  
  438.                 case    3:    /* Comment level */
  439.                     Project.CLevel = menu("Comment level",CLMenu,NULL)-1;
  440.                     PrVals[2].Val = (long)CLNames[Project.CLevel];
  441.                     sprintf(MOTD,"Comment level set to %s.",CLNames[Project.CLevel]);
  442.                 break;
  443.  
  444.                 case    4:
  445.                     Project.sep^=1;
  446.                     PrVals[3].Val^=1;
  447.                 break;
  448.  
  449.                 case    5:
  450.                     Project.flags ^= WIZFLG_PLOT;
  451.                     PrVals[4].Val = Project.flags&WIZFLG_PLOT;
  452.                 break;
  453.  
  454.                 case    6:
  455.                     Project.flags ^= WIZFLG_PSPLOT;
  456.                     PrVals[5].Val = Project.flags&WIZFLG_PSPLOT;
  457.                 break;
  458.  
  459.                 }
  460.             } while(i!=mcount(PrParms));
  461.             i=1;
  462.         break;
  463.  
  464.         case    2:    /* Pop params */
  465.             if(Project.NumPops>0) {
  466.                 do {
  467.                     if(Project.NumPops>1) {
  468.                         for(i=0;i!=Project.NumPops;i++) {
  469.                             tmenu[i] = Project.Pops[i].Name;
  470.                         }
  471.                         tmenu[i] = "Exit";
  472.                         tmenu[i+1] = 0;
  473.                         n = menu("Select Population",tmenu,NULL)-1;
  474.                         if(n==(mcount(tmenu)-1)) {
  475.                             break;
  476.                         }
  477.                     } else {
  478.                         n = 0;
  479.                     }
  480.                     PoVals[0].Val = (long)Project.Pops[n].Name;
  481.                     PoVals[1].Val = Project.Pops[n].Size;
  482.                     PoVals[2].Val = (long)GenomeNames[Project.Pops[n].Type];
  483.                     do {
  484.                         sprintf(buf,"Parameters for %s population",Project.Pops[n].Name);
  485.                         i = menu(buf,PoParms,PoVals);
  486.                         switch(i) {
  487.                         case    1:    /* Name */
  488.                             strcpy(buf,Project.Pops[n].Name);
  489.                             free(Project.Pops[n].Name);
  490.                             Project.Pops[n].Name = str_query("New name: ",buf);
  491.                             PoVals[0].Val = (long)Project.Pops[n].Name;
  492.                             sprintf(MOTD,"Name changed to %s.",Project.Pops[n].Name);
  493.                         break;
  494.  
  495.                         case    2:    /* Size */
  496.                             sprintf(buf,"New population size [%d]? : ",Project.Pops[n].Size);
  497.                             Project.Pops[n].Size = int_query(buf,Project.Pops[n].Size);
  498.                             PoVals[1].Val = Project.Pops[n].Size;
  499.                             sprintf(MOTD,"Size changed to %d.",Project.Pops[n].Size);
  500.                         break;
  501.  
  502.                         case    3: /* Genome type */
  503.                             i = menu("Select genome type",GenomeMenu,NULL);
  504.                             Project.Pops[n].Type = i-1;
  505.                             PoVals[2].Val=(long)GenomeNames[i-1];
  506.                             sprintf(MOTD,"Genome type set to %s.",GenomeNames[i-1]);
  507.                         break;
  508.  
  509.                         case    4: /* Flags */
  510.                             sprintf(buf,"Flags for %s population",Project.Pops[n].Name);
  511.                             do {
  512.                                 FlagVals[0].Val = (long)InitNames[Project.Pops[n].Flags[0]];
  513.                                 FlagVals[1].Val = (long)SelectNames[Project.Pops[n].Flags[1]];
  514.                                 FlagVals[2].Val = (long)CrossoverNames[Project.Pops[n].Flags[2]];
  515.                                 FlagVals[3].Val = Project.Pops[n].Flags[3];
  516.                                 FlagVals[4].Val = Project.Pops[n].Flags[4];
  517.                                 FlagVals[5].Val = Project.Pops[n].Flags[5];
  518.                                 FlagVals[6].Val = Project.Pops[n].Flags[6];
  519.                                 FlagVals[7].Val = Project.Pops[n].Flags[7];
  520.                                 FlagVals[8].Val = Project.Pops[n].Flags[8];
  521.                                 FlagVals[9].Val = Project.Pops[n].Flags[9];
  522.                                 FlagVals[10].Val = Project.Pops[n].Flags[10];
  523.                                 FlagVals[11].Val = Project.Pops[n].Flags[11];
  524.                                 FlagVals[12].Val = Project.Pops[n].Flags[12];
  525.                                 i = menu(buf,Flags,FlagVals);
  526.                                 switch(i) {
  527.                                 case    1:    /* Init */
  528.                                     Project.Pops[n].Flags[0] = menu("Select initialization type",InitNames,NULL)-1;
  529.                                 break;
  530.                                 case    2:    /* Select */
  531.                                     Project.Pops[n].Flags[1] = menu("Select selection type",SelectNames,NULL)-1;
  532.                                 break;
  533.                                 case    3:    /* Crossover */
  534.                                     Project.Pops[n].Flags[2] = menu("Select crossover type",CrossoverNames,NULL)-1;
  535.                                 break;
  536.                                 case    4:    /* Crowding */
  537.                                     Project.Pops[n].Flags[3] ^= 1;
  538.                                  break;
  539.                                 case    5:    /* Mutation */
  540.                                     Project.Pops[n].Flags[4] ^= 1;
  541.                                 break;
  542.                                 case    6:    /* Pre-Mutation */
  543.                                     Project.Pops[n].Flags[5] ^= 1;
  544.                                 break;
  545.                                 case    7:    /* Elitism */
  546.                                     Project.Pops[n].Flags[6] = int_query("Elite individuals [0]?",0);
  547.                                 break;
  548.                                 case    8:    /* Dump Worst */
  549.                                     Project.Pops[n].Flags[7] = int_query("Individuals to remove [0]?",0);
  550.                                 break;
  551.                                 case    9:    /* Init Dumped */
  552.                                     Project.Pops[n].Flags[8] ^= 1;
  553.                                 break;
  554.                                 case    10:    /* Newbies */
  555.                                     Project.Pops[n].Flags[9] = int_query("Individuals to regenerate [0]?",0);
  556.                                 break;
  557.                                 case    11:    /* Erase Best */
  558.                                     Project.Pops[n].Flags[10] ^= 1;
  559.                                 break;
  560.                                 case    12:    /* Make Stats */
  561.                                     Project.Pops[n].Flags[11] ^= 1;
  562.                                 break;
  563.                                 }
  564.                             } while(i!=mcount(Flags));
  565.                         break;
  566.  
  567.                         case    5: /* Report */
  568.                             sprintf(buf,"Report generation for %s population",Project.Pops[n].Name);
  569.                             do {
  570.                                 for(i=0;i!=6;i++) {
  571.                                     RFlagVals[i].Val = Project.Pops[n].RFlags[i];
  572.                                 }
  573.                                 RFlagVals[7].Val = Project.pass;
  574.                                 i = menu(buf,RFlagMenu,RFlagVals);
  575.                                 switch(i) {
  576.                                 case    1:
  577.                                 case    2:
  578.                                 case    3:
  579.                                 case    4:
  580.                                 case    5:
  581.                                 case    6:
  582.                                     Project.Pops[n].RFlags[i-1]^=1;
  583.                                 break;
  584.                                 case    7:
  585.                                     for(i=0;i!=6;i++) {
  586.                                         Project.Pops[n].RFlags[i]^=1;
  587.                                     }
  588.                                 break;
  589.                                 case    8:
  590.                                     Project.flags &= ~WIZFLG_MPASS;
  591.                                     i = int_query("Take average of how many passes [1] ?",1);
  592.                                     if(i>1) {
  593.                                         Project.flags |= WIZFLG_MPASS;
  594.                                         Project.pass = i;
  595.                                     } else {
  596.                                         i = 1;
  597.                                     }
  598.                                     RFlagVals[7].Val = i;
  599.                                     Project.pass = i;
  600.                                 break;
  601.                                 }
  602.                             } while(i!=mcount(RFlagMenu));
  603.                             for(i=0;i!=6;i++) {
  604.                                 if(Project.Pops[n].RFlags[i]!=0 && Project.Pops[n].Flags[11]==0) {
  605.                                     Project.Pops[n].Flags[11] = 1;
  606.                                     strcpy(MOTD,"Auto-enabled statistics.");
  607.                                     break;
  608.                                 }
  609.                             }
  610.                             i=0;
  611.                         break;
  612.                         }
  613.                     } while(i!=mcount(PoParms));
  614.                 } while(Project.NumPops>1);
  615.             } else {
  616.                 strcpy(MOTD,"Too few populations.");
  617.                 msg("Please set number of populations >= 1. [ENTER]");
  618.             }
  619.             i=2;
  620.         break;
  621.  
  622.         case    3:    /* Make project */
  623.             sprintf(buf,"Destination directory? [%s]? : ",CURRENT_DIR);
  624.             p = str_query(buf,CURRENT_DIR);
  625.             create_project(p);
  626.             free(p);
  627.         break;
  628.  
  629.         case    4:    /* Save */
  630.             sprintf(buf,"Save as [%s]? : ",Project.Name);
  631.             p = str_query(buf,Project.Name);
  632.             save_template(p);
  633.             free(p);
  634.         break;
  635.  
  636.         case    5:    /* Load */
  637.             p = str_query("Load project [" DEF_NAME "]? : ",DEF_NAME);
  638.             load_template(p);
  639.             free(p);
  640.         break;
  641.  
  642.         case    6: /* Quit */
  643.             if(!bool_query("Really quit " DEFN "? :",NO)) {
  644.                 i=0;
  645.             }
  646.         break;
  647.         }    /* switch() */
  648.     } while(i!=mcount(Menu1));
  649. } else {
  650.     printf("Too bad.\n");
  651. }
  652.  
  653. tixE:;
  654.  
  655. if(Project.Pops!=NULL) {
  656.     for(i=0;i!=Project.NumPops;i++) {
  657.         if(Project.Pops[i].Name!=NULL) {
  658.             free(Project.Pops[i].Name);
  659.         }
  660.     }
  661.     free(Project.Pops);
  662. }
  663.  
  664. if(Project.Name!=NULL) {
  665.     free(Project.Name);
  666. }
  667.  
  668. if(MOTD) {
  669.     free(MOTD);
  670. }
  671.  
  672. return(0);
  673. }
  674.  
  675. int    menu(char *title,char **items,struct VDisp *vs)
  676. {
  677. int i,n;
  678. char buf[255];
  679.  
  680. do {
  681.     printf(CLEAR "\n \x1b[4m%s\x1b[0m\n\n",title);
  682.     i=0;
  683.     while(items[i]!=NULL) {
  684.         printf("  %2d) %-24s",i+1,items[i]);
  685.         if(vs!=NULL) {
  686.             switch(vs[i].Type) {
  687.             case    MN_IGN:
  688.             break;
  689.  
  690.             case    MN_INT:
  691.                 printf("(%ld)",vs[i].Val);
  692.             break;
  693.  
  694.             case    MN_STR:
  695.                 if(vs[i].Val!=0) {
  696.                     printf("(%s)",(char *)vs[i].Val);
  697.                 }
  698.             break;
  699.  
  700.             case    MN_BOL:
  701.                 printf("(%s)",(vs[i].Val)?"Yes":"No");
  702.             break;
  703.  
  704.             default:
  705.                 fprintf(stderr,"menu: BUG!\n");
  706.             }
  707.         }
  708.         printf("\n");
  709.         i++;
  710.     }
  711.  
  712.     printf("\n==> ");
  713.  
  714.     if(MOTD!=NULL) {
  715.         printf("\n\nLast Message: %s\n\x1b[3A\x1b[4C",MOTD);
  716.     }
  717.  
  718.     fflush(stdout);
  719.  
  720.     fgets(buf,255,stdin);
  721.     n = atol(buf);
  722.  
  723. } while(n<1 || n>i);
  724.  
  725. printf("\x1b[J");fflush(stdout);
  726.  
  727. return(n);
  728. }
  729.  
  730. int msg(char *m)
  731. {
  732. char    buf[255];
  733. fflush(stdin);
  734. printf(m);
  735. fflush(stdout);
  736. fgets(buf,255,stdin);
  737. return((int)buf[0]);
  738. }
  739.  
  740. int int_query(char *m,int def)
  741. {
  742. int    i;
  743. char    buf[255],*p;
  744. fflush(stdin);
  745. printf(m);
  746. fflush(stdout);
  747. fgets(buf,255,stdin);
  748. i = strtol(buf,&p,0);
  749. if(p==buf) {
  750.     i = def;
  751. }
  752. return(i);
  753. }
  754.  
  755. char *str_query(char *m,char *def)
  756. {
  757. char    buf[255],*p;
  758. printf(m);
  759. fflush(stdout);
  760. fgets(buf,255,stdin);
  761. if(buf[0]=='\n') {
  762.     if(def!=NULL) {
  763.         strcpy(buf,def);
  764.     } else {
  765.         return(NULL);
  766.     }
  767. }
  768. if(strchr(buf,'\n')!=NULL) {
  769.     strchr(buf,'\n')[0]=0;
  770. }
  771. p = malloc(strlen(buf)+1);
  772. strcpy(p,buf);
  773. return(p);
  774. }
  775.  
  776. int mcount(char **s)
  777. {
  778. int i;
  779. i = -1;
  780. while(s[++i]!=0);
  781. return(i);
  782. }
  783.  
  784. int bool_query(char *s,int d)
  785. {
  786. int v;
  787. v = msg(s);
  788. switch(d) {
  789.  
  790. case    YES:
  791.     if(toupper(v)!=NO) {
  792.         v=1;
  793.     }
  794. break;
  795.  
  796. case    NO:
  797.     if(toupper(v)!=YES) {
  798.         v=0;
  799.     }
  800. break;
  801.  
  802. default:
  803.     fprintf(stderr,"bool_query: BUG!\n");
  804. }
  805.  
  806. return(v);
  807. }
  808.  
  809. void save_template(char *fname)
  810. {
  811. FILE *fp;
  812. struct stat State;
  813. int    r,i;
  814.  
  815. r=stat(fname,&State);
  816.  
  817. if(r==0) {
  818.     if(bool_query("File exists, overwrite? [y/N] : ",NO)) {
  819.         errno=ENOENT;
  820.     } else {
  821.         return;
  822.     }
  823. }
  824.  
  825. strcpy(MOTD,"Error while saving project template.");
  826.  
  827. if(errno==ENOENT) {
  828.     fp = fopen(fname,"wb");
  829.     if(fp!=NULL) {
  830.         fprintf(fp,"This file is a product of the Frobozz Magic File Company.\n\n");
  831.         fprintf(fp,"Project: %s\n",Project.Name);
  832.         fprintf(fp,"Populations: %d\n",Project.NumPops);
  833.         fprintf(fp,"CommentLevel: %d\n",Project.CLevel);
  834.         fprintf(fp,"Multisource: %d\n",Project.sep);
  835.         fprintf(fp,"Storyline: %d\n",Project.flags);
  836.         fprintf(fp,"Passcount: %d\n\n",Project.pass);
  837.         for(i=0;i!=Project.NumPops;i++) {
  838.             save_pop(fp,Project.Pops[i]);
  839.         }
  840.         strcpy(MOTD,"Project template saved.");
  841.         fclose(fp);
  842.     } else {
  843.         msg("save_template: General forseen non-fatal error occured. [ENTER]");
  844.     }
  845. } else {
  846.     msg("save_template: General forseen non-fatal error occured. [ENTER]");
  847. }
  848. return;
  849. }
  850.  
  851. void save_pop(FILE *fp,struct NPop pop)
  852. {
  853. int i;
  854.  
  855. fprintf(fp,"And now, the %s\n",pop.Name);
  856. fprintf(fp,"\t%d,%d,",pop.Size,pop.Type);
  857. for(i=0;i!=12;i++) {
  858.     fprintf(fp,"%d,",pop.Flags[i]);
  859. }
  860. for(i=0;i!=6;i++) {
  861.     fprintf(fp,"%d,",pop.RFlags[i]);
  862. }
  863. fprintf(fp,"*\n\n");
  864. }
  865.  
  866. void load_template(char *fname)
  867. {
  868. FILE *fp;
  869. struct stat State;
  870. int    r,i;
  871. char    buf[255];
  872.  
  873. r=stat(fname,&State);
  874.  
  875. if(r==0) {
  876.     fp = fopen(fname,"rb");
  877.     if(fp==NULL) {
  878.         strcpy(MOTD,"Unable to read template.");
  879.         msg("load_template: Irritating error, fopen() failed. [ENTER]");
  880.         return;
  881.     }
  882.     fgets(buf,255,fp);
  883.     if(!strcmp(buf,"This file is a product of the Frobozz Magic File Company.\n")) {
  884.  
  885.         if(Project.Pops!=NULL) {
  886.             for(i=0;i!=Project.NumPops;i++) {
  887.                 if(Project.Pops[i].Name!=NULL) {
  888.                     free(Project.Pops[i].Name);
  889.                 }
  890.             }
  891.             free(Project.Pops);
  892.         }
  893.  
  894.         if(Project.Name!=NULL) {
  895.             free(Project.Name);
  896.         }
  897.  
  898.         while(fgets(buf,255,fp),buf[0]=='\n');
  899.  
  900.         strchr(buf,'\n')[0]=0;
  901.         Project.Name = malloc(strlen(buf)-8);
  902.         strcpy(Project.Name,&buf[9]);
  903.  
  904.         while(fgets(buf,255,fp),buf[0]=='\n');
  905.         Project.NumPops = strtol(&buf[13],NULL,0);
  906.  
  907.         while(fgets(buf,255,fp),buf[0]=='\n');
  908.         Project.CLevel = strtol(&buf[14],NULL,0);
  909.  
  910.         while(fgets(buf,255,fp),buf[0]=='\n');
  911.         Project.sep = strtol(&buf[13],NULL,0);
  912.  
  913.         while(fgets(buf,255,fp),buf[0]=='\n');
  914.         Project.flags = strtol(&buf[11],NULL,0);
  915.  
  916.         while(fgets(buf,255,fp),buf[0]=='\n');
  917.         Project.pass = strtol(&buf[11],NULL,0);
  918.  
  919.         Project.Pops = malloc(Project.NumPops*sizeof(struct NPop));
  920.  
  921.         for(i=0;i!=Project.NumPops;i++) {
  922.             load_pop(fp,i);
  923.         }
  924.  
  925.         PrVals[0].Val = (long)Project.Name;
  926.         PrVals[1].Val = Project.NumPops;
  927.         PrVals[2].Val = (long)CLNames[Project.CLevel];
  928.         PrVals[3].Val = Project.sep;
  929.         PrVals[4].Val = Project.flags&WIZFLG_PLOT;
  930.         PrVals[5].Val = Project.flags&WIZFLG_PSPLOT;
  931.         sprintf(MOTD,"Template for the %s project loaded.",Project.Name);
  932.     } else {
  933.         strcpy(MOTD,"Unrecognized fileformat.");
  934.         msg("Unrecognized fileformat. [ENTER]");
  935.     }
  936.     fclose(fp);
  937. } else {
  938.     strcpy(MOTD,"Unable to examine template.");
  939.     msg("load_template: File inaccessible. [ENTER]");
  940. }
  941. return;
  942.  
  943. }
  944.  
  945. void load_pop(FILE *fp,int n)
  946. {
  947. int i;
  948. char buf[255];
  949.  
  950. while(fgets(buf,255,fp),strncmp(buf,"And now, the ",12));
  951. strchr(buf,'\n')[0]=0;
  952.  
  953. Project.Pops[n].Name = malloc(strlen(buf)-11);
  954. strcpy(Project.Pops[n].Name,&buf[13]);
  955.  
  956. fscanf(fp,"\t%d,%d,",&Project.Pops[n].Size,&Project.Pops[n].Type);
  957.  
  958. for(i=0;i!=12;i++) {
  959.     fscanf(fp,"%d,",&Project.Pops[n].Flags[i]);
  960. }
  961. for(i=0;i!=6;i++) {
  962.     fscanf(fp,"%d,",&Project.Pops[n].RFlags[i]);
  963. }
  964. return;
  965. }
  966.  
  967. void    create_project(char *dstdir)
  968. {
  969. FILE    *fp,*sp;
  970. char    *buf;
  971. struct NPop *Pops;
  972. struct stat State;
  973. int r,rep;
  974. int i,n;
  975.  
  976. buf = malloc(2048);
  977.  
  978. Pops = Project.Pops;
  979. strcpy(buf,dstdir);
  980. addpart(buf,Project.Name);
  981. strcat(buf,".c");
  982.  
  983. r=stat(buf,&State);
  984.  
  985. if(r==0) {
  986.     if(!bool_query("Project exists, overwrite? [y/N] :",NO)) {
  987.         free(buf);
  988.         return;
  989.     }
  990. }
  991.  
  992. rep=0;
  993. for(i=0;i!=Project.NumPops;i++) {
  994.     for(n=0;n!=6;n++) {
  995.         rep |= Pops[i].RFlags[n];
  996.     }
  997. }
  998.  
  999. Project.rep = rep;
  1000.  
  1001. fp = fopen(buf,"wb");
  1002. if(Project.sep) {
  1003.     strcpy(buf,dstdir);
  1004.     addpart(buf,Project.Name);
  1005.     strcat(buf,"Fitness.c");
  1006.     sp = fopen(buf,"wb");
  1007. } else {
  1008.     sp = fp;
  1009. }
  1010.  
  1011. if(fp!=NULL && sp!=NULL) {
  1012.  
  1013.     switch(Project.CLevel) {
  1014.     case    1:
  1015.         fprintf(fp,"/*\n *\t%s.c\n *\tCreated by the GAP Conjurer.\n *\n */\n\n",Project.Name);
  1016.     break;
  1017.  
  1018.     case    2:
  1019.     case    3:
  1020.         fprintf(fp,"/*\n *\t%s.c\n *\tCreated by the GAP Conjurer.\n *\n *\n * Populations:\n",Project.Name);
  1021.         for(i=0;i!=Project.NumPops;i++) {
  1022.             fprintf(fp," *\t%s population.\n",Pops[i].Name);
  1023.         }
  1024.         fprintf(fp," */\n\n");
  1025.     break;
  1026.  
  1027.     case    4:
  1028.         fprintf(fp,"/*\n *\t%s.c\n *\tCreated by the GAP Conjurer.\n *\n *\n * Populations:\n",Project.Name);
  1029.         for(i=0;i!=Project.NumPops;i++) {
  1030.             fprintf(fp," *\t%s population. (%d individuals initially)\n",Pops[i].Name,Pops[i].Size);
  1031.             fprintf(fp," *\t\t %-20s(%s)\n",Flags[0],InitNames[Pops[i].Flags[0]]);
  1032.             fprintf(fp," *\t\t %-20s(%s)\n",Flags[1],SelectNames[Pops[i].Flags[1]]);
  1033.             fprintf(fp," *\t\t %-20s(%s)\n",Flags[2],CrossoverNames[Pops[i].Flags[2]]);
  1034.             fprintf(fp," *\t\t %-20s(%s)\n",Flags[3],(Pops[i].Flags[3])?"Yes":"No");
  1035.             fprintf(fp," *\t\t %-20s(%s)\n",Flags[4],(Pops[i].Flags[4])?"Yes":"No");
  1036.             fprintf(fp," *\t\t %-20s(%s)\n",Flags[5],(Pops[i].Flags[5])?"Yes":"No");
  1037.             fprintf(fp," *\t\t %-20s(%d)\n",Flags[6],Pops[i].Flags[6]);
  1038.             fprintf(fp," *\t\t %-20s(%d)\n",Flags[7],Pops[i].Flags[7]);
  1039.             fprintf(fp," *\t\t %-20s(%s)\n",Flags[8],(Pops[i].Flags[8])?"Yes":"No");
  1040.             fprintf(fp," *\t\t %-20s(%d)\n",Flags[9],Pops[i].Flags[9]);
  1041.             fprintf(fp," *\t\t %-20s(%s)\n",Flags[10],(Pops[i].Flags[10])?"Yes":"No");
  1042.             fprintf(fp," *\t\t %-20s(%s)\n",Flags[11],(Pops[i].Flags[11])?"Yes":"No");
  1043.             fprintf(fp," *\n");
  1044.         }
  1045.         fprintf(fp," */\n\n");
  1046.     break;
  1047.  
  1048.     default:
  1049.         ;
  1050.     }
  1051.  
  1052.  
  1053.     if(Project.CLevel>2) {
  1054.         fprintf(fp,"/* Includes follow */\n");
  1055.     }
  1056.  
  1057.  
  1058.     i = 0;
  1059.     while(includes[i]!=NULL) {
  1060.         fprintf(fp,"#include <%s.h>\n",includes[i++]);
  1061.     }
  1062.  
  1063.     if(rep!=0) {
  1064.         fprintf(fp,"#include \"report.h\"\n");
  1065.     }
  1066.  
  1067.     fprintf(fp,"\n%s",(Project.CLevel>0)?"/* Population defines. */\n\n":"");
  1068.  
  1069.     buf[0]=0;
  1070.     for(i=0;i!=Project.NumPops;i++) {
  1071.         if(Project.CLevel>1) {
  1072.             sprintf(buf,"\t/* Initial size of %s population. */",Pops[i].Name);
  1073.         }
  1074.         fprintf(fp,"#define\t%sSIZE\t%d%s\n",Pops[i].Name,Pops[i].Size,buf);
  1075.     }
  1076.  
  1077.     fprintf(fp,"\n%s",(Project.CLevel>0)?"/* Population structures. */\n\n":"");
  1078.  
  1079.     for(i=0;i!=Project.NumPops;i++) {
  1080.  
  1081.         fprintf(fp,"\n/*===== %s =====*/\n\n",Pops[i].Name);
  1082.  
  1083.         fprintf(fp,"#%s\tZINIT%d\n",(Pops[i].Flags[0]==1)?"define":"undef",i);
  1084.         fprintf(fp,"#%s\tMPCROSS%d\n\n",(Pops[i].Flags[2]==1)?"define":"undef",i);
  1085.  
  1086.         switch(Pops[i].Type) {
  1087.         case    PTYPE_Bitstring:
  1088.             fprintf(fp,"#define\tSIZE%d\t%d%s\n\n",i,1,(Project.CLevel>1)?"\t/* _BYTE_ length of bitstring. */":"");
  1089.         break;
  1090.  
  1091.         case    PTYPE_Bitmatrix:
  1092.             fprintf(fp,"#define\tWIDTH%d\t%d\n",i,8);
  1093.             fprintf(fp,"#define\tHEIGHT%d\t%d\n",i,8);
  1094.             fprintf(fp,"#define\tXBYTES%d\t((WIDTH%d+7)>>3)\n\n",i,i);
  1095.         break;
  1096.  
  1097.         case    PTYPE_BRVector:
  1098.             fprintf(fp,"#define\tVLENGTH%d\t%d\n\nstatic double Constraints%d[VLENGTH%d][2] = {%s\n",i,DEF_BRVLEN,i,i,(Project.CLevel>0)?" /* Constraint ranges. */":"");
  1099.             for(n=0;n!=DEF_BRVLEN-1;n++) {
  1100.                 fprintf(fp,"   {-1.0,1.0},%s\n",(Project.CLevel>2)?"\t/* This comment is here just to irritate you. */":"");
  1101.             }
  1102.                 fprintf(fp,"   {-1.0,1.0}\n};\n\n");
  1103.         break;
  1104.  
  1105.         case    PTYPE_Custom:
  1106.         break;
  1107.  
  1108.         default:
  1109.             fprintf(fp,"/* Error in population type. */\n\n");
  1110.         }
  1111.  
  1112.         fprintf(fp,"struct %s {\n",Pops[i].Name);
  1113.         switch(Pops[i].Type) {
  1114.         case    PTYPE_Bitstring:
  1115.             fprintf(fp,"   unsigned char Data[SIZE%d];\n",i);
  1116.         break;
  1117.  
  1118.         case    PTYPE_Bitmatrix:
  1119.             fprintf(fp,"   unsigned char matrix[HEIGHT%d][XBYTES%d];\n   int x,y,xb;\n",i,i);
  1120.         break;
  1121.  
  1122.         case    PTYPE_BRVector:
  1123.             fprintf(fp,"   double\tv[%d];\n",DEF_BRVLEN);
  1124.         break;
  1125.  
  1126.         case    PTYPE_Custom:
  1127.             if(Project.CLevel>0) {
  1128.                 fprintf(fp,"   /* Define custom data for %s here. */\n",Pops[i].Name);
  1129.             }
  1130.         break;
  1131.  
  1132.         default:
  1133.             fprintf(fp,"/* Error in population type. */\n");
  1134.         }
  1135.         fprintf(fp,"};\n\n");
  1136.     }
  1137.  
  1138.     if(Project.CLevel>0) {
  1139.         fprintf(fp,"/* Function prototypes follow. */\n\n");
  1140.     }
  1141.  
  1142.     if(Project.CLevel>1) {
  1143.         fprintf(fp,"/* Fitness functions. */\n\n");
  1144.     }
  1145.  
  1146.     for(i=0;i!=Project.NumPops;i++) {
  1147.         fprintf(fp,"%sdouble %sFitness(struct %s *);\n",(Project.sep!=0)?"extern ":"",Pops[i].Name,Pops[i].Name);
  1148.     }
  1149.  
  1150.     fprintf(fp,"\n");
  1151.     if(Project.CLevel>1) {
  1152.         fprintf(fp,"/* Other functions. */\n\n");
  1153.     }
  1154.  
  1155.     for(i=0;i!=Project.NumPops;i++) {
  1156.         fprintf(fp,"void Init%s(struct %s *);\n",Pops[i].Name,Pops[i].Name);
  1157.         if(Pops[i].Flags[4]!=0) {
  1158.             fprintf(fp,"void Mutate%s(struct %s *);\n",Pops[i].Name,Pops[i].Name);
  1159.         }
  1160.         fprintf(fp,"void Cross%s(struct %s *,struct %s *);\n",Pops[i].Name,Pops[i].Name,Pops[i].Name);
  1161.         fprintf(fp,"double Compare%s(struct %s *,struct %s *,int);\n",Pops[i].Name,Pops[i].Name,Pops[i].Name);
  1162.         fprintf(fp,"void Kill%s(struct %s *);\n",Pops[i].Name,Pops[i].Name);
  1163.         fprintf(fp,"\n");
  1164.     }
  1165.  
  1166. /* Create main() */
  1167.  
  1168.     if(Project.CLevel>0) {
  1169.         fprintf(fp,"/*=== Main program starts here. ===*/\n\n");
  1170.     }
  1171.  
  1172.     fprintf(fp,"int main(int cnt,char *arg[])\n{\nint\ti%s;\nint\tGenerations=10;\n",(Project.flags&WIZFLG_MPASS)?",n":"");
  1173.  
  1174.     for(i=0;i!=Project.NumPops;i++) {
  1175.         fprintf(fp,"struct Population *%sPop;\n",Pops[i].Name);
  1176.     }
  1177.  
  1178.     if(rep!=0) {
  1179.         for(i=0;i!=Project.NumPops;i++) {
  1180.             for(n=0;n!=6;n++) {
  1181.                 if(Pops[i].RFlags[n]!=0) {
  1182.                     fprintf(fp,"struct Report *%sRep;\n",Pops[i].Name);
  1183.                     break;
  1184.                 }
  1185.             }
  1186.         }
  1187.     }
  1188.  
  1189.     fprintf(fp,"\n");    
  1190.  
  1191.     for(i=0;i!=Project.NumPops;i++) {
  1192.         fprintf(fp,"struct TagItem %sInitTags[] = {\n"\
  1193.         "   {POP_Init,(IPTR)Init%s},\n"\
  1194.         "   {POP_Destruct,(IPTR)Kill%s},\n"\
  1195.         "   {POP_Cache,TRUE},\n"\
  1196.         "   {TAG_DONE,0L}\n};\n\n",Pops[i].Name,Pops[i].Name,Pops[i].Name);
  1197.     }
  1198.  
  1199.     for(i=0;i!=Project.NumPops;i++) {
  1200.         fprintf(fp,"struct TagItem %sEvolveTags[] = {",Pops[i].Name);
  1201.         for(n=0;n!=12;n++) {
  1202.             fprintf(fp,"\n   {%s,",FlagTags[n]);
  1203.             switch(n) {
  1204.             case    0:
  1205.                 fprintf(fp,"(IPTR)%sFitness},",Pops[i].Name);
  1206.             break;
  1207.             case    1:
  1208.                 fprintf(fp,"%s},",SelectDefs[Pops[i].Flags[n]]);
  1209.             break;
  1210.             case    2:
  1211.                 fprintf(fp,"(IPTR)Cross%s},",Pops[i].Name);
  1212.             break;
  1213.             case    3:
  1214.                 fprintf(fp,"%s},",TF(Pops[i].Flags[n]));
  1215.             break;
  1216.             case    4:
  1217.                 if(Pops[i].Flags[n]!=0) {
  1218.                     fprintf(fp,"(IPTR)Mutate%s},",Pops[i].Name);
  1219.                 } else {
  1220.                     fprintf(fp,"NULL},");
  1221.                 }
  1222.             break;
  1223.             case    5:
  1224.                 fprintf(fp,"%s},",TF(Pops[i].Flags[n]));
  1225.             break;
  1226.             case    6:
  1227.                 fprintf(fp,"%d},",Pops[i].Flags[n]);
  1228.             break;
  1229.             case    7:
  1230.                 fprintf(fp,"%d},",Pops[i].Flags[n]);
  1231.             break;
  1232.             case    8:
  1233.                 fprintf(fp,"%s},",TF(Pops[i].Flags[n]));
  1234.             break;
  1235.             case    9:
  1236.                 fprintf(fp,"%d},",Pops[i].Flags[n]);
  1237.             break;
  1238.             case    10:
  1239.                 fprintf(fp,"%s},",TF(Pops[i].Flags[n]));
  1240.             break;
  1241.             case    11:
  1242.                 fprintf(fp,"%s},",TF(Pops[i].Flags[n]));
  1243.             break;
  1244.             default:
  1245.                 fprintf(fp,"/* Tag creation error. */\n");
  1246.             }
  1247.         }
  1248.         fprintf(fp,"\n   {TAG_DONE,0L}\n};\n\n");
  1249.     }
  1250.  
  1251.     if(Project.flags&WIZFLG_MPASS) {
  1252.         fprintf(fp,"struct TagItem ReportTags[] = {\n");
  1253.         fprintf(fp,"\t{REP_Generations,0},\n\t{REP_Multipass,TRUE},\n");
  1254.         fprintf(fp,"\t{TAG_DONE,0L}\n};\n\n");
  1255.     }
  1256.  
  1257.     fprintf(fp,"if(cnt>1) {\n   if(strcmp(arg[1],\"-h\")==0 || strcmp(arg[1],\"--help\")==0) {\n"\
  1258.         "      fprintf(stderr,\"Useage:\\n\\n%%s <Generations>\\n\\n\",arg[0]);\n      return(0);\n   }\n"\
  1259.         "   Generations = atoi(arg[1]);\n}\n\nif(Generations<1) {\n   Generations=10;\n}\n\n");
  1260.  
  1261.     fprintf(fp,"InitRand(time(NULL));\n\n");
  1262.  
  1263.     if(Project.flags&WIZFLG_MPASS) {
  1264.         fprintf(fp,"ReportTags[0].ti_Data = (IPTR)Generations;\n\n");
  1265.     }
  1266.  
  1267.     if(rep!=0) {
  1268.         for(i=0;i!=Project.NumPops;i++) {
  1269.             for(n=0;n!=6;n++) {
  1270.                 if(Pops[i].RFlags[n]!=0) {
  1271.                     fprintf(fp,"%sRep = MakeReport(\"%s\",%s);\n",Pops[i].Name,Pops[i].Name,(Project.flags&WIZFLG_MPASS)?"ReportTags":"NULL");
  1272.                     break;
  1273.                 }
  1274.             }
  1275.         }
  1276.     }
  1277.  
  1278.     fprintf(fp,"\n");
  1279.  
  1280.     if(Project.flags&WIZFLG_MPASS) {
  1281.         fprintf(fp,"for(n=0;n!=%d;n++) {",Project.pass);
  1282.         if(Project.CLevel>2) {
  1283.             sprintf(buf,"\t/* Perform %d runs of this GA. */",Project.pass);
  1284.         }
  1285.         fprintf(fp,"\n\n");
  1286.     }
  1287.  
  1288.     for(i=0;i!=Project.NumPops;i++) {
  1289.         fprintf(fp,"%s%sPop = CreatePopulation(%sSIZE,sizeof(struct %s),%sInitTags);\n",(Project.flags&WIZFLG_MPASS)?"\t":"",Pops[i].Name,Pops[i].Name,Pops[i].Name,Pops[i].Name);
  1290.     }
  1291.  
  1292.     fprintf(fp,"\n%sif(",(Project.flags&WIZFLG_MPASS)?"\t":"");
  1293.     for(i=0;i!=(Project.NumPops-1);i++) {
  1294.         fprintf(fp,"%sPop!=NULL && ",Pops[i].Name);
  1295.     }
  1296.     fprintf(fp,"%sPop!=NULL) {\n",Pops[i].Name);
  1297.  
  1298.     fprintf(fp,"%s\tfor(i=0;i!=Generations;i++) {\n",(Project.flags&WIZFLG_MPASS)?"\t":"");
  1299.  
  1300.     for(i=0;i!=Project.NumPops;i++) {
  1301.         fprintf(fp,"%s\t\t%sPop = Evolve(%sPop,%sEvolveTags);\n",(Project.flags&WIZFLG_MPASS)?"\t":"",Pops[i].Name,Pops[i].Name,Pops[i].Name);
  1302.     }
  1303.  
  1304.     if(rep!=0) {
  1305.         fprintf(fp,"\n");
  1306.         for(i=0;i!=Project.NumPops;i++) {
  1307.             buf[0]=0;
  1308.             for(n=0;n!=6;n++) {
  1309.                 if(Pops[i].RFlags[n]!=0) {
  1310.                     strcat(buf,RepDefs[n]);
  1311.                     strcat(buf,"|");
  1312.                 }
  1313.             }
  1314.             if(buf[0]!=0) {
  1315.                 buf[strlen(buf)-1]=0;
  1316.                 fprintf(fp,"%s\t\tDoReport(%sRep,%sPop,%s);\n",(Project.flags&WIZFLG_MPASS)?"\t":"",Pops[i].Name,Pops[i].Name,buf);
  1317.             }
  1318.         }
  1319.     }
  1320.  
  1321.     fprintf(fp,"%s\t}\n%s}\n\n",(Project.flags&WIZFLG_MPASS)?"\t":"",(Project.flags&WIZFLG_MPASS)?"\t":"");
  1322.  
  1323.     for(i=0;i!=Project.NumPops;i++) {
  1324.         fprintf(fp,"%sif(%sPop!=NULL)DeletePopulation(%sPop);\n",(Project.flags&WIZFLG_MPASS)?"\t":"",Pops[i].Name,Pops[i].Name);
  1325.     }
  1326.  
  1327.     if(Project.flags&WIZFLG_MPASS) {
  1328.         fprintf(fp,"}\n");
  1329.     }
  1330.  
  1331.     fprintf(fp,"\n");
  1332.  
  1333.     if(rep!=0) {
  1334.         for(i=0;i!=Project.NumPops;i++) {
  1335.             for(n=0;n!=6;n++) {
  1336.                 if(Pops[i].RFlags[n]!=0) {
  1337.                     fprintf(fp,"if(%sRep!=NULL)EndReport(%sRep);\n",Pops[i].Name,Pops[i].Name);
  1338.                     break;
  1339.                 }
  1340.             }
  1341.         }
  1342.     }
  1343.  
  1344.     if(rep!=0) {
  1345.         if(Project.flags&WIZFLG_PSPLOT) {
  1346.             fprintf(fp,"\nsystem(\"gnuplot MakePS\");\n");
  1347.         }
  1348.         if(Project.flags&WIZFLG_PLOT) {
  1349.             fprintf(fp,"\nsystem(\"gnuplot ShowReport\");\n");
  1350.         }
  1351.     }
  1352.  
  1353.     fprintf(fp,"\nreturn(0);\n}\n\n");
  1354.  
  1355. /* == End of main() writing code == */
  1356.  
  1357. if(Project.sep!=0) {
  1358.     fprintf(sp,"#include <GAP.h>\n#include <math.h>\n\n");
  1359.     for(i=0;i!=Project.NumPops;i++) {
  1360.         fprintf(sp,"double %sFitness(struct %s *);\n",Pops[i].Name,Pops[i].Name);
  1361.     }
  1362.     fprintf(sp,"\n");
  1363. }
  1364.  
  1365. if(Project.CLevel>0) {
  1366.     fprintf(sp,"/*=== Fitness functions ===*/\n");
  1367.     if(Project.CLevel>2) {
  1368.         fprintf(sp,"/* Below here are the functions which define how\n * fit an individual is - commponly known as fitness functions.\n */\n\n");
  1369.     }
  1370. }
  1371.  
  1372. for(i=0;i!=Project.NumPops;i++) {
  1373.     fprintf(sp,"double %sFitness(struct %s *Polly)\n{\ndouble fitness=0.0;\n",Pops[i].Name,Pops[i].Name);
  1374.     if(Project.CLevel>0) {
  1375.         fprintf(sp,"/* Write fitness function for %s here. */\n",Pops[i].Name);
  1376.     }
  1377.     fprintf(sp,"return(fitness);\n}\n\n");
  1378. }
  1379.  
  1380. if(Project.CLevel>0) {
  1381.     fprintf(fp,"/*=== Crossover, Mutation etc. functions. ===*/\n\n");
  1382. }
  1383.  
  1384. /* Functions */
  1385.  
  1386. for(i=0;i!=Project.NumPops;i++) {
  1387.     switch(Pops[i].Type) {
  1388.     case    PTYPE_Bitstring:
  1389.         filtdump(fp,Bitstring_c,i);
  1390.     break;
  1391.  
  1392.     case PTYPE_Bitmatrix:
  1393.         filtdump(fp,Bitmatrix_c,i);
  1394.     break;
  1395.  
  1396.     case PTYPE_BRVector:
  1397.         filtdump(fp,BRVector_c,i);
  1398.     break;
  1399.  
  1400.     case PTYPE_Custom:
  1401.         filtdump(fp,Skeleton_c,i);
  1402.     break;
  1403.  
  1404.     }
  1405. }
  1406.  
  1407. /* == magic == */
  1408.  
  1409.     if(Project.CLevel>0) {
  1410.         fprintf(fp,"\n/* vi: set ts=3: */ /* vim magic */\n");
  1411.     }
  1412.  
  1413.     fclose(fp);
  1414.     if(fp!=sp) {
  1415.         fclose(sp);
  1416.     }
  1417.  
  1418.  
  1419. /* Report files. */
  1420.  
  1421. if(rep!=0) {
  1422.     strcpy(buf,dstdir);
  1423.     addpart(buf,"report.h");
  1424.     if(file_write(buf)) {
  1425.         if((fp=fopen(buf,"wb"))!=NULL) {
  1426.             fwrite(report_h,report_h_SIZE,1,fp);
  1427.             fclose(fp);
  1428.         }
  1429.     }
  1430.  
  1431.     strcpy(buf,dstdir);
  1432.     addpart(buf,"report.c");
  1433.     if(file_write(buf)) {
  1434.         if((fp=fopen(buf,"wb"))!=NULL) {
  1435.             fwrite(report_c,report_c_SIZE,1,fp);
  1436.             fclose(fp);
  1437.         }    
  1438.     }
  1439. }
  1440.  
  1441.  
  1442. /* Makefile */
  1443.  
  1444. strcpy(buf,dstdir);
  1445. addpart(buf,"Makefile");
  1446. if(file_write(buf)) {
  1447.     if((fp=fopen(buf,"wb"))!=NULL) {
  1448.         filtdump(fp,mk,0);
  1449.         fclose(fp);
  1450.     }
  1451. }
  1452.  
  1453. /* PostScript(tm) generation script */
  1454.  
  1455. if(Project.flags&WIZFLG_PSPLOT) {
  1456.     strcpy(buf,dstdir);
  1457.     addpart(buf,"MakePS");
  1458.     if(file_write(buf)) {
  1459.         if((fp=fopen(buf,"wb"))!=NULL) {
  1460.             fprintf(fp,"\n# PostScript(tm) generation script for GNUPlot.\n# Created by the GAP Conjurer.\n\n");
  1461.             fprintf(fp,"set terminal postscript landscape enhanced monochrome\n\n");
  1462.             for(i=0;i!=Project.NumPops;i++) {
  1463.                 for(n=0;n!=6;n++) {
  1464.                     if(Pops[i].RFlags[n]!=0) {
  1465.                         fprintf(fp,"set output \"%s%s.ps\"\n",Pops[i].Name,RepDefs[n]);
  1466.                         fprintf(fp,"set title \"%s %s\"\n",Pops[i].Name,RepNames[n]);
  1467.                         fprintf(fp,"plot \"%s.%s\" with lines\n\n",Pops[i].Name,RepExts[n]);
  1468.                     }
  1469.                 }
  1470.             }
  1471.             fclose(fp);
  1472.         }
  1473.     }
  1474. }
  1475.  
  1476. if(Project.flags&WIZFLG_PLOT) {
  1477.     strcpy(buf,dstdir);
  1478.     addpart(buf,"ShowReport");
  1479.     if(file_write(buf)) {
  1480.         if((fp=fopen(buf,"wb"))!=NULL) {
  1481.             fprintf(fp,"\n# Report display script for GNUPlot.\n# Generated by the GAP Conjurer.\n\n");
  1482.             buf[0] = 0;
  1483.             for(i=0;i!=Project.NumPops;i++) {
  1484.                 for(n=0;n!=6;n++) {
  1485.                     if(Pops[i].RFlags[n]!=0) {
  1486.                         sprintf(&buf[strlen(buf)],"\t\"%s.%s\" with lines,\\\n",Pops[i].Name,RepExts[n]);
  1487.                     }
  1488.                 }
  1489.             }
  1490.             buf[strlen(buf)-3] = 0;
  1491.             fprintf(fp,"plot \\\n%s",buf);
  1492.             fprintf(fp,"\npause -1 \"Press enter to continue...\"");
  1493.             fclose(fp);
  1494.         }
  1495.     }
  1496. }
  1497.  
  1498.     strcpy(MOTD,"Created project.");
  1499.  
  1500. } else {
  1501.     strcpy(MOTD,"Error creating project.");
  1502.     msg("create_project: Unable to open file for writing. [ENTER]");
  1503. }
  1504.  
  1505. free(buf);
  1506.  
  1507. return;
  1508. }
  1509.  
  1510. char *addpart(char *buf,char *fname)
  1511. {
  1512. int l;
  1513.  
  1514. l = strlen(buf);
  1515.  
  1516. #ifdef    AMIGA
  1517. if(buf[l-1]==DIR_SEPARATOR || buf[l-1]==':' || buf[0]==0) {
  1518. #else
  1519. if(buf[l-1]==DIR_SEPARATOR || buf[0]==0) {
  1520. #endif
  1521.     strcat(buf,fname);
  1522. } else {
  1523.     buf[l]=DIR_SEPARATOR;
  1524.     buf[l+1]=0;
  1525.     strcat(buf,fname);
  1526. }
  1527. return(buf);
  1528. }
  1529.  
  1530. void filtdump(FILE *fp,char *data,int indx)
  1531. {
  1532. int    i,n;
  1533. int    z;
  1534.  
  1535. i = -1;
  1536. while((z=data[++i])) {
  1537.     if(z=='$') {
  1538.         z=data[++i];
  1539.         switch(z) {
  1540.         case    '1':
  1541.         case    '2':
  1542.         case    '3':
  1543.         case    '4':
  1544.             n = z-'1';
  1545.             if(Project.CLevel>n) {
  1546.                 while((z=data[++i])!='$') {
  1547.                     fputc(z,fp);
  1548.                 }
  1549.             } else {
  1550.                 while((z=data[++i])!='$');
  1551.             }
  1552.         break;
  1553.  
  1554.         case    'N':
  1555.             fprintf(fp,Project.Pops[indx].Name);
  1556.         break;
  1557.  
  1558.         case    'I':
  1559.             fprintf(fp,"%d",indx);
  1560.         break;        
  1561.  
  1562.         case    '$':
  1563.             fputc('$',fp);
  1564.         break;
  1565.  
  1566.         case    'P':
  1567.             fprintf(fp,Project.Name);
  1568.         break;
  1569.  
  1570.         case    'U':
  1571.             if(Project.sep!=0) {
  1572.                 while((z=data[++i])!='$' || data[i+1]=='$') {
  1573.                     if(z=='$') {
  1574.                         i++;
  1575.                         fputc('$',fp);
  1576.                     } else {
  1577.                         fputc(z,fp);
  1578.                     }
  1579.                 }
  1580.             } else {
  1581.                 while((z=data[++i])!='$' || data[i+1]=='$') {
  1582.                     if(z=='$') {
  1583.                         i++;
  1584.                     }
  1585.                 }
  1586.             }
  1587.         break;
  1588.  
  1589.         case    'R':
  1590.             if(Project.rep!=0) {
  1591.                 while((z=data[++i])!='$' || data[i+1]=='$') {
  1592.                     if(z=='$') {
  1593.                         i++;
  1594.                         fputc('$',fp);
  1595.                     } else {
  1596.                         fputc(z,fp);
  1597.                     }
  1598.                 }
  1599.             } else {
  1600.                 while((z=data[++i])!='$' || data[i+1]=='$') {
  1601.                     if(z=='$') {
  1602.                         i++;
  1603.                     }
  1604.                 }
  1605.             }
  1606.         break;
  1607.  
  1608.         default:
  1609.             fprintf(stderr,"Illegal control token, corrupted memory?\n");
  1610.         }
  1611.     } else {
  1612.         fputc(z,fp);
  1613.     }
  1614. };
  1615.  
  1616. }
  1617.  
  1618. int file_write(char *fname)
  1619. {
  1620. int    r,i=0;
  1621. struct stat State;
  1622. char    buf[255];
  1623.  
  1624. r=stat(fname,&State);
  1625.  
  1626. if(r==0) {
  1627.     sprintf(buf,"%s exists, overwrite? " DEFN " : ",fname);
  1628.     if(bool_query(buf,NO)) {
  1629.         i = 1;
  1630.     }
  1631. } else {
  1632.     switch(errno) {
  1633.  
  1634.     case    ENOENT:
  1635.         i = 1;
  1636.     break;
  1637.  
  1638.     case    EBUSY:
  1639.         msg("File already in use. [ENTER]");
  1640.         i = 0;
  1641.     break;
  1642.  
  1643.     case    EPERM:
  1644.         msg("Access denied. [ENTER]");
  1645.         i = 0;
  1646.     break;
  1647.  
  1648.     default:
  1649.         sprintf(buf,"Unexpected forseen but unknown error on file \"%s\". [ENTER]",fname);
  1650.         msg(buf);
  1651.         i = 0;
  1652.     }
  1653. }
  1654.  
  1655. return(i);
  1656. }
  1657.  
  1658.